﻿//=============================================================================
// Project  : NIPO Component Framework
// File    : ProcessingPlugin.cs
// Author  : Bernhard Dieber (Bernhard.Dieber@uni-klu.ac.at)
// Copyright 2010 by Bernhard Dieber
// This code is published under the Microsoft Public License (Ms-PL).  A copy
// of the license should be distributed with the code.  It can also be found
// at the project website: http://NIPO.CodePlex.com.   This notice, the
// author's name, and all copyright notices must remain intact in all
// applications, documentation, and source files.
//=============================================================================

using System;
using System.Threading;
using NIPO.Attributes;
using NIPO.Data;

namespace NIPO.Plugins
{
    /// <summary>
    /// A processing plugin does all the data processing in a NIPO instance. It is the core element of a processing chain<br />
    /// A ProcessingPlugin receives data from one or many InputPlugins via the <see cref="ProcessingPlugin.ProcessData"/> Method which is registered as Eventhandler for every <see cref="InputPlugin.NewData"/> event by default.<br />
    /// </summary>
    /// <remarks>To implement a new processing plugin inherit from <see cref="ProcessingPlugin"/>.<br/>
    /// <see cref="ProcessingPlugin.ProcessData"/> will be automatically registered as eventHandler for <see cref="InputPlugin.NewData"/>. Perform your data processing tasks in this method.<br />
    /// Whenever a sensful chunk of processed data is available pass it on to the output via the <see cref="ProcessingPlugin.RaiseNewData"/> method.<br />
    /// </remarks>
    public abstract class ProcessingPlugin : IPOPlugin
    {
        /// <summary>
        /// Occurs when the processing plugin has new data to pass on
        /// </summary>
        [DataEvent]
        public event NIPOEventHandler NewData;

        /// <summary>
        /// This function receives data from every InputPlugin for further processing
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="NIPOEventArgs"/> instance containing the event data.</param>
        public abstract void ProcessData(object sender, NIPOEventArgs e);

        /// <summary>
        /// Passes on data to the next Plugin.
        /// </summary>
        /// <param name="dto">A data object to pass to the next processing chain element</param>
        protected void RaiseNewData(DataTransferObject dto)
        {
            if (NewData == null) return;
            //Log.WriteInfo("NewData");
            if (ConfigurationObject == null || ConfigurationObject.AsynchronousInvoke)
            {

                ThreadPool.QueueUserWorkItem(delegate
                                                  {
                                                      NewData.Invoke(this, new NIPOEventArgs(dto, ID));
                                                  });
            }
            else
                NewData(this, new NIPOEventArgs(dto, ID));
        }


        internal override void InternalReset()
        {
            NewData = null;
        }
    }
}